#!/usr/bin/env python

import sys
import os
import pprint
import re
from optparse import OptionParser

changeLineRe = re.compile(r'^([0-9]+)c\1$')
codeComponentLineRe = re.compile(r'^[<>]\s*SubType\s*=\s*"(Code|Component)"$')

global options

def output(s):
    if options.noisy:
        print s

def run(command):
    output(command)
    lines = [line.strip() for line in os.popen(command).readlines()]
    return lines

def isItJustCodeComponentChanges(fileName):
    lines = run('cvs -f -q diff ' + fileName)

    # skip the header - Index/equals/RCS/retrieving/diff and so on
    lines = lines[5:]

    if 0 != len(lines) % 4:
        return False

    i = 0
    while i < len(lines):
        if changeLineRe.match(lines[i]) is None:
            output(lines[i] + ' doesn\'t match')
            return False
        i += 1
        
        if codeComponentLineRe.match(lines[i]) is None:
            output(lines[i] + ' doesn\'t match')
            return False
        i += 1

        if lines[i] != '---':
            output(lines[i] + ' doesn\'t match')
            return False
        i += 1

        if codeComponentLineRe.match(lines[i]) is None:
            output(lines[i] + ' doesn\'t match')
            return False
        i += 1

    return True

def main(args=None):
    if args == None:
        args = sys.argv[1:]

    parser = OptionParser()
    parser.add_option('-n', action='store_true', dest='doNothing', default=False,
                      help='Do not execute anything that will change the disk')
    parser.add_option('-q', '--quiet',
                      action='store_false', dest='noisy', default=True,
                      help='be somewhat quiet')

    global options
    (options, args) = parser.parse_args(args)

    revertables = []
    for line in run('cvs -f -q -n update'):
        if line.startswith('M ') and line.endswith('.csproj'):
            if isItJustCodeComponentChanges(line[2:]):
                revertables.append(line[2:])

    for fileName in revertables:
        if options.noisy:
            output(fileName + ' is just Code/Component changes')

        if not options.doNothing:
            os.remove(fileName)

    if 0 < len(revertables):
        command = ' '.join(['cvs -f -q update',] + revertables)
        if not options.doNothing:
            run (command)

    return 0


if __name__ == '__main__':
    sys.exit(main())

